#include "dashboard.h"
#include "ui_dashboard.h"
#include <QPainter>
#include <QtMath>
#include <QDebug>

Dashboard::Dashboard(QWidget *parent)
	: QWidget(parent)
    , ui(new Ui::Dashboard)
{
	ui->setupUi(this);
    animation.setTargetObject(this);      //
    animation.setPropertyName("value");   // 绑定value属性，animation启动后， 会调用setValue 函数
    animation.setDuration(300);           // 300ms
    animation.setEasingCurve(QEasingCurve::OutBack);        // 动画特效
}

Dashboard::Dashboard(int minValue, int tickValue, int tickCount, int value, QString text, QWidget *parent)
    : Dashboard(parent)
{
	set(minValue, tickValue, tickCount, value, text);
}

Dashboard::~Dashboard()
{
    delete ui;
}

void Dashboard::set(int minValue, int tickValue, int tickCount, int value, QString text)
{
	this->minValue = minValue;
	this->tickValue = tickValue;
	this->tickCount = tickCount;
    this->currentValue = value;
	this->text = text; 
}

void Dashboard::updateValue(int value)
{
    animation.stop();
    animation.setStartValue(this->currentValue); // 动画初始值
    animation.setEndValue(value);               // 动画最终值
    animation.start();
}

int Dashboard::value()
{
    return currentValue;
}

void Dashboard::setValue(double value)
{
    currentValue = value;
    update();
}

void Dashboard::setText(QString text)
{
    this->text=text;
    update();
}

double Dashboard::valueToAngle(double value)
{
    // 根据value算出指针需要旋转的角度
    return 300.0/(tickCount-1)*((value-minValue)/tickValue) + 120;
}

void Dashboard::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);       // 抗锯齿
    double radius = qMin<int>(this->width(),this->height())/2-5;    // 仪表盘外圆半径
    QPoint center = QPoint(this->width()/2, this->height()/2);      // 中心点
    painter.setBrush(QBrush(Qt::black));                            // 设置画刷为黑色
    painter.drawEllipse(center, (int)radius, (int)radius);          // 画外圆

    painter.setPen(QPen(Qt::white));
    QFont font;
    int pixelSize = int(radius/7);
    font.setPixelSize(pixelSize);
    painter.setFont(font);
    QTextOption option;
    option.setAlignment(Qt::AlignCenter);    // 文字居中

    painter.translate(center);             // 画笔移动到中心点center
    painter.rotate(120);                    // 顺时钟旋转90度， 以时钟3点方向为0度
    double angle = 300.0 / (tickCount-1);
    for(int i=1;i<=tickCount;i++){
        
        painter.drawLine(QPoint(radius*0.75, 0), QPoint(radius*0.9, 0));
        if(i!=tickCount){
            painter.save();
            for(int j=0;j<9;j++) {    // 每个大刻度间， 画9个小刻度， 分成10等分
                double angle2 = 300.0/(tickCount-1)/10.0;
                painter.rotate(angle2);
                painter.drawLine(QPoint(radius*0.85, 0), QPoint(radius*0.9, 0));
            }
            painter.restore();
        }
		painter.rotate(angle);

    }
    painter.rotate(-60 - angle);  // 画笔旋转角度复原
    for(int i=0;i<tickCount;i++) {
        double angle =(120.0 + 300.0/(tickCount-1)*i)/180.0*M_PI;    // 计算大刻度标注需要旋转的角度
        QPoint p3 = QPoint(radius*0.6*qCos(angle),radius*0.6*qSin(angle));
        QRectF r = QRectF(p3-QPoint(pixelSize,pixelSize),p3+QPoint(pixelSize,pixelSize));  // 标准显示的矩形区域
        painter.drawText(r, QString::number(minValue + tickValue*i),option);      // 指定矩形区域画标注
    }


    // 在6点方向画仪表盘的标注
    angle =M_PI/2;
    QPoint p = QPoint(radius*0.5*qCos(angle),radius*0.5*qSin(angle));
    QRectF r = QRectF(p-QPoint(radius,radius),p+QPoint(radius,radius));
    painter.drawText(r, text, option);

    // 在6点方向画仪表盘的值
    p = QPoint(radius*0.8*qCos(angle),radius*0.8*qSin(angle));
    r = QRectF(p-QPoint(radius,radius),p+QPoint(radius,radius));
    painter.drawText(r, QString::number((int)currentValue), option);

    // 指针旋转到目标角度
    painter.rotate(valueToAngle(this->currentValue));
    drawArrow(painter);  // 画指针， 虚函数， 可重载此函数实现自定义指针
}

void Dashboard::drawArrow(QPainter &painter)
{
    double radius = qMin<int>(this->width(),this->height())/2-5;    // 仪表盘外圆半径
    QColor color(Qt::white);
    painter.setBrush(QBrush(color));
    QPen pen = painter.pen();
    pen.setColor(color);
    painter.setPen(pen);
    painter.drawEllipse(QPoint(0,0), int(radius*0.1), int(radius*0.1));  // 画指针中心上的小圆
    QPolygon polygon;
    polygon.push_back(QPoint(-(radius*0.2),-(radius*0.04)));
    polygon.push_back(QPoint(-(radius*0.2),(radius*0.04)));
    polygon.push_back(QPoint(radius*0.9,0));
    painter.drawPolygon(polygon);    // 画三角形，表示指针
}
